package com.angel.kuaidi.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import com.angel.kuaidi.utils.UtilsLog;

public class XmlParserManager {
	protected static final String ENCODING = "UTF-8";

	private static XmlPullParserFactory sFactory;
	static {
		try {
			sFactory = XmlPullParserFactory.newInstance();
		} catch (XmlPullParserException e) {
			throw new IllegalStateException("Could not create a factory");
		}
	}

	/**
	 * 获取实体
	 * 
	 * @param <T>
	 * @param in
	 *            输入流
	 * @param root
	 *            结点
	 * @param clazz
	 *            实体Class
	 * @return
	 * @throws Exception
	 */
	public static <T> T getBean(InputStream in, Class<T> clazz)
			throws Exception {
		T t = null;
		int nodecount = 0;
		try {
			XmlPullParser parser = createXmlPullParser(in);
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				switch (eventType) {
				case XmlPullParser.START_DOCUMENT:// 开始元素事件
					t = clazz.newInstance();
					break;
				case XmlPullParser.START_TAG:// 开始结点

					String tagName = parser.getName().toLowerCase();
					try {
						if (t != null) {
							Field field = t.getClass().getField(tagName);
							if (field != null) {
								nodecount++;
								try {
									field.set(t, parser.nextText());
								} catch (Exception e) {
									field.set(t, parser.getText());
								}
							}
						}
					} catch (Exception e) {
					}
					break;
				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SouFunNetException(e.getMessage(), e);
		} finally {
			try {
				if (in != null)
					in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (nodecount == 0)
			t = null;
		return t;
	}

	/**
	 * 获取实体
	 * 
	 * @param <T>
	 * @param in
	 *            输入流
	 * @param root
	 *            结点
	 * @param clazz
	 *            实体Class
	 * @return
	 * @throws Exception
	 */
	public static <T> T getBean(InputStream in, String root, Class<T> clazz)
			throws Exception {
		T t = null;
		int nodecount = 0;
		try {
			XmlPullParser parser = createXmlPullParser(in);
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				switch (eventType) {
				case XmlPullParser.START_TAG:// 开始结点

					String tagName = parser.getName().toLowerCase();
					try {
						if (t != null) {
							Field field = t.getClass().getField(tagName);
							if (field != null) {
								try {
									nodecount++;
									field.set(t, parser.nextText());
								} catch (Exception e) {
									field.set(t, parser.getText());
								}
							}
						}
					} catch (Exception e) {
					}
					if (tagName.equals(root)) {
						t = clazz.newInstance();
					}
					break;
				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SouFunNetException(e.getMessage(), e);
		} finally {
			try {
				if (in != null)
					in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (nodecount == 0)
			t = null;
		return t;
	}

	/**
	 * 获取list数据
	 * 
	 * @param <T>
	 * @param in
	 *            输入流
	 * @param root
	 *            结点
	 * @param clazz
	 *            实体Class
	 * @return
	 * @throws Exception
	 */
	public static <T> ArrayList<T> getBeanList(InputStream in, String root,
			Class<T> clazz) throws Exception {
		ArrayList<T> list = null;
		int nodecount = 0;
		T t = null;
		try {
			XmlPullParser parser = createXmlPullParser(in);
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				switch (eventType) {
				case XmlPullParser.START_DOCUMENT:// 开始元素事件
					list = new ArrayList<T>();
					break;

				case XmlPullParser.START_TAG:// 开始结点

					String tagName = parser.getName().toLowerCase();

					try {
						if (t != null) {
							Field field = t.getClass().getField(tagName);
							if (field != null) {
								try {
									nodecount++;
									field.set(t, parser.nextText());
								} catch (Exception e) {
									field.set(t, parser.getText());
								}

							}
						}
					} catch (Exception e) {
					}

					if (tagName.equals(root)) {
						t = clazz.newInstance();
					}
					break;

				case XmlPullParser.END_TAG:// 结束结点
					if (root.equalsIgnoreCase(parser.getName())) {
						if (t != null) {
							list.add(t);
							t = null;
						}
					}
					break;

				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SouFunNetException(e.getMessage(), e);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (nodecount == 0)
			list = null;
		return list;
	}

	/**
	 * 获取list数据
	 * 
	 * @param <T>
	 * @param in
	 *            输入流
	 * @param root
	 *            结点
	 * @param clazz
	 *            实体Class
	 * @return
	 * @throws Exception
	 */
	public static <T> ArrayList<T> getBeanList(String xml, String root,
			Class<T> clazz) throws Exception {
		ArrayList<T> list = null;
		int nodecount = 0;
		T t = null;
		try {
			XmlPullParser parser = sFactory.newPullParser();
			parser.setInput(new StringReader(xml));
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				switch (eventType) {
				case XmlPullParser.START_DOCUMENT:// 开始元素事件
					list = new ArrayList<T>();
					break;

				case XmlPullParser.START_TAG:// 开始结点

					String tagName = parser.getName().toLowerCase();

					try {
						if (t != null) {
							Field field = t.getClass().getField(tagName);
							if (field != null) {
								try {
									nodecount++;
									field.set(t, parser.nextText());
								} catch (Exception e) {
									field.set(t, parser.getText());
								}

							}
						}
					} catch (Exception e) {
					}

					if (tagName.equals(root)) {
						t = clazz.newInstance();
					}
					break;

				case XmlPullParser.END_TAG:// 结束结点
					if (root.equalsIgnoreCase(parser.getName())) {
						if (t != null) {
							list.add(t);
							t = null;
						}
					}
					break;

				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SouFunNetException(e.getMessage(), e);
		}
		if (nodecount == 0)
			list = null;
		return list;
	}

	
	public static String getString(InputStream is) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(is,
				ENCODING));
		String str = "";
		StringBuffer s = new StringBuffer("");
		while ((str = in.readLine()) != null) {
			s.append(str);
		}
		try {
			is.close();
		} catch (Exception e) {
			// TODO: handle exception
		}

		return s.toString();
	}

	public static final XmlPullParser createXmlPullParser(InputStream is) {
		XmlPullParser parser;
		try {
			parser = sFactory.newPullParser();
			if (UtilsLog.isTest) {
				StringBuffer sb = new StringBuffer();
				if (UtilsLog.isTest) {
					String str = "";
					BufferedReader in = new BufferedReader(
							new InputStreamReader(is, ENCODING));
					while ((str = in.readLine()) != null) {
						sb.append(str);
					}
					is.close();
				}
				parser.setInput(new StringReader(sb.toString()));
			} else {
				parser.setInput(is, ENCODING);
			}
		} catch (XmlPullParserException e) {
			throw new IllegalArgumentException();
		} catch (IOException e) {
			throw new IllegalArgumentException();
		}
		return parser;
	}
}
